#include "init.h"
#include "units.h"
#include "players.h"
#include "gui.h"
#include <fstream>
#include <iostream>
#include <vector>
#include <sstream>



/*
1-100 - teren
20000 - prekazka nepruchozi
30000 - prekazka neprustrelna
*/



unit_types* unit_types::get_instance()
{
	static unit_types inst( 0 );
	return &inst;
};



bool unit_types::load_types( const char* file )
{
	std::ifstream fin;
	fin.open( file, std::ifstream::in );
	if ( !fin.good() )
	{
		std::cout << "ERROR WHILE OPENING UNIT TYPES FILE" << std::endl;
		return false;
	}
	std::string unit_line;
	for ( ; ; )
	{
		std::getline( fin, unit_line );
		if ( fin.fail() )
		{
			break;
		}
		if ( !parse_unit_line ( unit_line ) )
		{
			std::cout << "ERROR WHILE READING UNIT TYPES FILE" << std::endl;
			return false;
		}
	}
	fin.close();
	std::cout << "UNIT TYPES LOADED SUCCESSFULLY" << std::endl;
	return true;
};



bool unit_types::parse_unit_line( std::string ul )
{
	if ( ul[0] == '#' )
		return true;
	std::istringstream sstr( ul );
	sstr.ignore( ul.size(), '"' );
	string name;
	std::getline( sstr, name, '"' );
	if ( name == "" )
		return true;
	unsigned int price;
	unsigned int range;
	unsigned int health;
	unsigned int shield;
	unsigned int weapon;
	unsigned int cost_move;
	unsigned int cost_fire;
	std::vector< std::pair< string, string > > icons( parameters::get_instance()->game_parameters[ "MAX_PL" ] );
	string sound_f;
	sstr >> price;
	sstr >> range;
	sstr >> health;
	sstr >> shield;
	sstr >> weapon;
	sstr >> cost_move;
	sstr >> cost_fire;
	if ( ( price < 1 ) || ( range < 1 ) || ( health < 1 ) || ( shield < 1 ) || ( weapon < 1 ) || ( cost_move < 1 ) || ( cost_fire < 1 ) )
		return false;
	if ( health > 20000 )
		health = 20000;
	for ( unsigned int i = 0; i < parameters::get_instance()->game_parameters[ "MAX_PL" ]; ++i )
	{
		string icon_n;
		string icon_s;
		sstr >> icon_n;
		sstr >> icon_s;
		icons[ i ] = std::make_pair< string, string >( icon_n, icon_s );
	}
	sstr >> sound_f;

	if ( sstr.fail() )
		return false;

	prototypes::get_instance()->set_new_unit( name, price, range, health, shield, weapon, cost_move, cost_fire );
	game_gui::get_instance()->graphics->set_new_units_resources( name, icons, sound_f );
	std::cout << "LOADED UNIT TYPE: " << name << std::endl;

	return true;
};



parameters* parameters::get_instance()
{
	static parameters inst( 0 );
	return &inst;
};



bool parameters::load_parameters( const char* file )
{
	std::ifstream fin;
	fin.open( file, std::ifstream::in );
	if ( !fin.good() )
	{
		std::cout << "ERROR WHILE OPENING PARAMETERS FILE" << std::endl;
		return false;
	}
	std::string param_line;
	for ( ; ; )
	{
		std::getline( fin, param_line );
		if ( fin.fail() )
		{
			break;
		}
		if ( !parse_param_line ( param_line ) )
		{
			std::cout << "ERROR WHILE READING PARAMETERS FILE" << std::endl;
			return false;
		}
	}
	fin.close();

	if ( !check_parameters() )
	{
		std::cout << "ERROR, SOME PARAMETERS ARE MISSING" << std::endl;
		return false;
	}

	if ( check_values() )
	{
		std::cout << "PARAMETERS LOADED SUCCESSFULLY" << std::endl;		
	}
	else
	{
		std::cout << "PARAMETERS LOADED, SOME VALUES CHANGED TO MAX" << std::endl;	
	}

	return true;
};



bool parameters::parse_param_line( std::string pl )
{
	if ( pl[0] == '#' )
		return true;
	std::istringstream sstr( pl );

	string cat;
	string name;
	string subname;
	double value;

	sstr >> cat;
	if ( cat == "" )
		return true;
	sstr >> name;

	if ( cat == "AI" )
	{
		sstr >> subname;
	}
	else
	{
		subname = "";
	}

	sstr >> value;
	if ( sstr.fail() )
		return false;

	if ( cat == "GAME" )
		game_parameters[ name ] = ( unsigned int )value;
	else if ( cat == "GUI" )
		gui_parameters[ name ] = ( unsigned int )value;
	else if ( cat == "AI" )
		ai_parameters[ name ][ subname ] = value;

	std::cout << "LOADED PARAMETER: " << cat << " - " << name << " " << subname << std::endl;

	return true;
};



bool parameters::check_parameters()
{
	if ( ( game_parameters.find( "MAX_PL" ) == game_parameters.end() ) ||
		 ( game_parameters.find( "MAX_UNITS" ) == game_parameters.end() ) ||
		 ( game_parameters.find( "START_TIME" ) == game_parameters.end() ) ||
		 ( game_parameters.find( "START_MONEY" ) == game_parameters.end() ) )
		 return false;

	if ( ( gui_parameters.find( "ICON_W" ) == gui_parameters.end() ) ||
		 ( gui_parameters.find( "ICON_H" ) == gui_parameters.end() ) )
		 return false;

	if ( ( ai_parameters.find( "GENERAL" ) == ai_parameters.end() ) )
		return false;

	if ( ( ai_parameters[ "GENERAL" ].find( "ai_delay" ) == ai_parameters[ "GENERAL" ].end() ) || 
		 ( ai_parameters[ "GENERAL" ].find( "health_coef" ) == ai_parameters[ "GENERAL" ].end() ) ||
		 ( ai_parameters[ "GENERAL" ].find( "weapon_coef" ) == ai_parameters[ "GENERAL" ].end() ) ||
		 ( ai_parameters[ "GENERAL" ].find( "shield_coef" ) == ai_parameters[ "GENERAL" ].end() ) ||
		 ( ai_parameters[ "GENERAL" ].find( "range_coef" ) == ai_parameters[ "GENERAL" ].end() ) ||
		 ( ai_parameters[ "GENERAL" ].find( "cost_move_coef" ) == ai_parameters[ "GENERAL" ].end() ) ||
		 ( ai_parameters[ "GENERAL" ].find( "cost_fire_coef" ) == ai_parameters[ "GENERAL" ].end() ) ||
		 ( ai_parameters[ "GENERAL" ].find( "position_coef" ) == ai_parameters[ "GENERAL" ].end() ) ||
		 ( ai_parameters[ "GENERAL" ].find( "attack_coef" ) == ai_parameters[ "GENERAL" ].end() ) ||
		 ( ai_parameters[ "GENERAL" ].find( "danger_coef" ) == ai_parameters[ "GENERAL" ].end() ) ||
		 ( ai_parameters[ "GENERAL" ].find( "test_range" ) == ai_parameters[ "GENERAL" ].end() ) ||
		 ( ai_parameters[ "SEARCH" ].find( "depth" ) == ai_parameters[ "SEARCH" ].end() ) )
		 return false;

	return true;
};



bool parameters::check_values()
{
	bool ok = true;

	if ( game_parameters[ "MAX_PL" ] < 2 )
	{
		game_parameters[ "MAX_PL" ] = 2;
		ok = false;
	}
	if ( game_parameters[ "MAX_UNITS" ] < 1 )
	{
		game_parameters[ "MAX_UNITS" ] = 1;
		ok = false;
	}
	if ( game_parameters[ "START_TIME" ] < 1 )
	{
		game_parameters[ "START_TIME" ] = 1;
		ok = false;
	}
	if ( game_parameters[ "START_MONEY" ] < 1 )
	{
		game_parameters[ "START_MONEY" ] = 1;
		ok = false;
	}
	if ( gui_parameters[ "ICON_W" ] < 1 )
	{
		gui_parameters[ "ICON_W" ] = 1;
		ok = false;
	}
	if ( gui_parameters[ "ICON_H" ] < 1 )
	{
		gui_parameters[ "ICON_H" ] = 1;
		ok = false;
	}
	if ( ai_parameters[ "GENERAL" ][ "test_range" ] < 0 )
	{
		ai_parameters[ "GENERAL" ][ "test_range" ] = 0;
		ok = false;
	}
	if ( ai_parameters[ "GENERAL" ][ "ai_delay" ] < 0 )
	{
		ai_parameters[ "GENERAL" ][ "ai_delay" ] = 0;
		ok = false;
	}
	if ( ai_parameters[ "SEARCH" ][ "depth" ] < 1 )
	{
		ai_parameters[ "SEARCH" ][ "depth" ] = 1;
		ok = false;
	}

	return ok;
};